package com.frog.service.friend.page;


import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

@Getter
@Setter
@Slf4j
public class PageInfo<T> implements Serializable {
    // 结果集
    private List<T> list;
    // 当前页
    private int pageNum;
    // 每页的数量
    private int pageSize;
    // 总记录数
    private long total;

    // 当前页的数量
    private int size;
    // 总页数
    private int pages;


    // 前一页
    private int prePage;
    // 下一页
    private int nextPage;


    // 是否为第一页
    private boolean isFirstPage = false;
    // 是否为最后一页
    private boolean isLastPage = false;
    // 是否有前一页
    private boolean hasPreviousPage = false;
    // 是否有下一页
    private boolean hasNextPage = false;


    // 分页数据json格式
    private String pageSet;


    public PageInfo(List<T> list) throws Exception {
        if (list == null) throw new Exception("PageInfo list is null");
        this.list = list;
        this.total = list.size();
        this.size = list.size();
    }

    public PageInfo(List<T> list, int pageNum, int pageSize, long total)  {
        // 验证结果集、当前页、每页的数量
        verifyStartAndEndRow(list, pageNum, pageSize);
        // 设置总记录数
        setTotal(total);
        // 判定页面边界
        judgePageBoudary();
        // 分页数据json格式
        setPageSet();
    }


    /**
     * 验证结果集、当前页、每页的数量
     */
    public void verifyStartAndEndRow(List<T> list, int pageNum, int pageSize) {
        this.list = list == null ? new ArrayList<>() : list;
        this.size = this.list.size();
        // 当前页判断规则
        // 1、pageNum > 0,     显示当前页码, 否则默认页码 1
        // 2、pageNum < pages, 显示当前页码, 否则默认最大页码
        this.pageNum = pageNum > 0 ? pageNum : 1;
        // 每页的数量
        // 1、pageSize = 0,    显示每页的数量默认10条
        // 2、pageSize > 0,    显示每页的数量
        // 3、pageSize < 0,    显示所有数据,默认-1
        this.pageSize = pageSize < 0 ? -1 : pageSize == 0 ? 10 : pageSize;
    }


    /**
     * 设置总记录数、总页数、下一页
     */
    public void setTotal(long total) {

        this.total = total < 0 ? -1 : total;

        if (total == -1) {
            pages = 1;
            return;
        }

        if (pageSize > 0) {
            pages = (int) (total / pageSize + ((total % pageSize == 0) ? 0 : 1));
        } else {
            pages = 0;
        }

        //分页合理化，针对不合理的页码自动处理
        if (pageNum > pages) {
            if (pages != 0) {
                pageNum = pages;
            }
        }
    }


    /**
     * 判定页面边界
     */
    private void judgePageBoudary() {
        isFirstPage = pageNum == 1;
        isLastPage = pageNum == pages || pages == 0;
        hasPreviousPage = pageNum > 1;
        hasNextPage = pageNum < pages;
        prePage = hasPreviousPage ? pageNum - 1 : pageNum;
        nextPage = hasNextPage ? pageNum + 1 : pageNum;
    }


    private void setPageSet() {
        this.pageSet = "page=" + nextPage + "&pageSize=" + pageSize + "&hasMore=" + hasNextPage;
    }
}